package annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 标识{@link Singleton}类用于依赖注入的构造器
 *
 * <p>依赖注入(Dependency Injection)是个听起来有点吓人的词，其实简单理解就是将一个对象所需的其他对象通过构造方法传入
 * <p>例如，在使用依赖注入前，我们有一个Image类
 * <pre> {@code
 *
 *  public class Image {
 *     private Pixel[][] pixels;
 *     private ImageFile imageFile;
 *
 *     public Image(String path) throws UnsupportedDataTypeException {
 *         String extension = path.substring(path.lastIndexOf("."));
 *         switch (extension) {
 *             case ".jpg": case ".jpeg":
 *                 imageFile = new JpgImage(path);
 *                 break;
 *             case ".png":
 *                 imageFile = new PngImage(path);
 *                 break;
 *             default:
 *                 throw new UnsupportedDataTypeException();
 *         }
 *
 *         imageFile.load(pixels);
 *     }
 *
 *     public void save() {
 *         imageFile.save(pixels);
 *     }
 *
 *     public Pixel pixelAt(int x, int y) {
 *         return pixels[y][x];
 *     }
 *     ...
 *  }
 * }</pre>
 * <p>事实上，图片文件的创建过程不应该放在Image类的构造方法中，因为Image类是专注处理具体图像的，文件处理应该自立门户
 * <p>因此，将构造方法改为如下形式就是依赖注入
 * <pre> {@code
 *
 *  public class Image {
 *     private Pixel[][] pixels;
 *     private ImageFile imageFile;
 *
 *     public Image(ImageFile imageFile) {
 *         this.imageFile = imageFile;
 *         imageFile.load(pixels);
 *     }
 *
 *     public void save() {
 *         imageFile.save(pixels);
 *     }
 *
 *     public Pixel pixelAt(int x, int y) {
 *         return pixels[y][x];
 *     }
 *     ...
 *  }
 * }</pre>
 */
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface DependencyInjection {
}
